﻿using LiteDB;
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

namespace LiteDb
{
    /// <summary>
    /// 设备固定配置存储模型 (key-value方式，每个设备只有一个配置)
    /// </summary>
    public class DeviceFixedSetting
    {
        public const string CollectionName = nameof(DeviceFixedSetting);
        
        [BsonId(true)]
        public int Id { get; set; }
        
        /// <summary>
        /// 关联的分组设备ID
        /// </summary>
        public int GroupDeviceId { get; set; }
        
        /// <summary>
        /// 设置类别 (NetworkLocal, NetworkOray, NetworkHj212)
        /// </summary>
        public string Category { get; set; } = string.Empty;
        
        /// <summary>
        /// 原始值 (存储原始的配置数据)
        /// </summary>
        public string Config { get; set; } = string.Empty;

    }

    /// <summary>
    /// MQTT网络配置存储模型 (支持增删改查)
    /// </summary>
    public class NetworkMqttSetting
    {
        public const string CollectionName = nameof(NetworkMqttSetting);
        
        [BsonId(true)]
        public int Id { get; set; }

        /// <summary>
        /// 关联的分组设备ID
        /// </summary>
        public int GroupDeviceId { get; set; }

        /// <summary>
        /// 配置名称
        /// </summary>
        public string Name { get; set; } = string.Empty;

        /// <summary>
        /// 原始值 (存储原始的配置数据)
        /// </summary>
        public string Config { get; set; } = string.Empty;
    }

    /// <summary>
    /// 固定设置类别常量
    /// </summary>
    public static class FixedSettingCategories
    {
        public const string NetworkLocal = "NetworkLocal";
        public const string NetworkOray = "NetworkOray";
        public const string NetworkHj212 = "NetworkHj212";
    }

    /// <summary>
    /// 设备固定配置Repository (只支持查询和更新)
    /// </summary>
    public class DeviceFixedSettingRepository
    {
        private readonly ILiteCollection<DeviceFixedSetting> _collection;

        public DeviceFixedSettingRepository(LiteDatabase db)
        {
            _collection = db.GetCollection<DeviceFixedSetting>(DeviceFixedSetting.CollectionName);
            
            // 创建索引
            _collection.EnsureIndex(x => x.GroupDeviceId);
            _collection.EnsureIndex(x => x.Category);
            _collection.EnsureIndex("DeviceCategory", x => new { x.GroupDeviceId, x.Category }, true); // 唯一复合索引
            
            // 自动初始化默认配置
            InitializeDefaultSettings();
        }

        /// <summary>
        /// 初始化默认配置（在创建Repository时自动调用）
        /// </summary>
        public object InitializeDefaultSettings()
        {
            try
            {
                // 首先检查集合是否已经有配置，如果有就不需要初始化
                var existingSettings = _collection.FindAll().ToList();
                if (existingSettings.Any())
                {
                    return ApiResponse.Success(new { 
                        createdCount = 0,
                        existingCount = existingSettings.Count,
                        settings = existingSettings.Select(s => s.Category).ToList()
                    }, $"配置已存在 {existingSettings.Count} 个，跳过初始化");
                }

                var now = DateTime.Now;
                var createdSettings = new List<DeviceFixedSetting>();

                // 1. 创建默认本地网络配置
                string strDefault = @"{
                  ""lanMode"": ""single"",
                  ""wanConfig"": {
                    ""ipType"": ""manual"",
                    ""ipAddress"": ""192.168.2.101"",
                    ""subnetMask"": ""255.255.255.0"",
                    ""gateway"": ""192.168.2.1"",
                    ""dns"": ""192.168.2.1""
                  },
                  ""lanNetwork"": {
                    ""gateway"": ""192.168.10.1"",
                    ""subnetMask"": ""255.255.255.0"",
                    ""startIp"": ""192.168.10.2"",
                    ""endIp"": ""192.168.10.254""
                  },
                  ""fourGNetwork"": {
                    ""apn"": ""CMNET"",
                    ""authType"": ""NONE"",
                    ""username"": """",
                    ""password"": """"
                  },
                  ""wifiNetwork"": {
                    ""ssid"": """",
                    ""password"": """",
                    ""ipType"": ""manual"",
                    ""ipAddress"": ""192.168.3.2"",
                    ""subnetMask"": ""255.255.255.0"",
                    ""gateway"": ""255.255.255.0"",
                    ""dns"": ""255.255.255.0""
                  }
                }";

                var localSetting = new DeviceFixedSetting
                {
                    GroupDeviceId = 1, // 固定值，因为每个设备数据库只有一个设备
                    Category = FixedSettingCategories.NetworkLocal,
                    Config = strDefault
                };

                _collection.Insert(localSetting);
                createdSettings.Add(localSetting);

                // 2. 创建默认花生壳网络配置
                var orayConfig = new NetworkOrayConfig
                {
                    Name = "花生壳网络",
                    Domain = "example.oray.com",
                    Port = 502,
                    Username = "",
                    Password = ""
                };

                var oraySetting = new DeviceFixedSetting
                {
                    GroupDeviceId = 1, // 固定值，因为每个设备数据库只有一个设备
                    Category = FixedSettingCategories.NetworkOray,
                    Config = JsonConvert.SerializeObject(orayConfig)
                };

                _collection.Insert(oraySetting);
                createdSettings.Add(oraySetting);

                // 3. 创建默认HJ212网络配置
                var hj212Config = new NetworkHj212Config
                {
                    Name = "HJ212网络",
                    ServerUrl = "http://data.server.com",
                    MN = "",
                    Password = "",
                    HeartbeatInterval = 30
                };

                var hj212Setting = new DeviceFixedSetting
                {
                    GroupDeviceId = 1, // 固定值，因为每个设备数据库只有一个设备
                    Category = FixedSettingCategories.NetworkHj212,
                    Config = JsonConvert.SerializeObject(hj212Config)
                };

                _collection.Insert(hj212Setting);
                createdSettings.Add(hj212Setting);

                return ApiResponse.Success(new { 
                    createdCount = createdSettings.Count,
                    settings = createdSettings.Select(s => s.Category).ToList()
                }, $"初始化了 {createdSettings.Count} 个默认配置");
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"初始化默认配置失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取固定配置
        /// </summary>
        public object GetSetting(string category)
        {
            try
            {
                var setting = _collection.FindOne(s => s.Category == category);
                
                if (setting == null)
                {
                    return ApiResponse.Fail("配置不存在", null, ApiResponseCode.NotFound);
                }

                return ApiResponse.Success(setting.Config);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"获取配置失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 更新固定配置
        /// </summary>
        public object UpdateSetting(string category, object configData)
        {
            try
            {
                var setting = _collection.FindOne(s => s.Category == category);

                if (setting == null)
                {
                    return ApiResponse.Fail("配置不存在，请先初始化设备配置", null, ApiResponseCode.NotFound);
                }

                // 修复 CS8601: 可能的 null 引用赋值
                setting.Config = configData?.ToString() ?? string.Empty;

                bool updated = _collection.Update(setting);
                return updated ?
                    ApiResponse.Success(setting.Id, "配置更新成功") :
                    ApiResponse.Fail("配置更新失败");
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"更新配置失败: {ex.Message}");
            }
        }

        #region 专用配置方法

        /// <summary>
        /// 保存本地网络设置
        /// </summary>
        public object SaveLocalNetworkSettings(object param)
        {
            return UpdateSetting(FixedSettingCategories.NetworkLocal, param);
        }

        /// <summary>
        /// 获取本地网络设置
        /// </summary>
        public object GetLocalNetworkSettings(object param)
        {
            return GetSetting(FixedSettingCategories.NetworkLocal);
        }

        /// <summary>
        /// 保存HJ212网络设置
        /// </summary>
        public object SaveHj212NetworkSettings(object param)
        {
            return UpdateSetting(FixedSettingCategories.NetworkHj212, param);
        }

        /// <summary>
        /// 获取HJ212网络设置
        /// </summary>
        public object GetHj212NetworkSettings(object param)
        {
            return GetSetting(FixedSettingCategories.NetworkHj212);
        }

        /// <summary>
        /// 保存花生壳网络设置
        /// </summary>
        public object SaveOrayNetworkSettings(object param)
        {
            return UpdateSetting(FixedSettingCategories.NetworkOray, param);
        }

        /// <summary>
        /// 获取花生壳网络设置
        /// </summary>
        public object GetOrayNetworkSettings(object param)
        {
            return GetSetting(FixedSettingCategories.NetworkOray);
        }

        #endregion
    }

    /// <summary>
    /// MQTT网络配置Repository (支持完整的增删改查)
    /// </summary>
    public class NetworkMqttSettingRepository
    {
        private readonly ILiteCollection<NetworkMqttSetting> _collection;

        public NetworkMqttSettingRepository(LiteDatabase db)
        {
            _collection = db.GetCollection<NetworkMqttSetting>(NetworkMqttSetting.CollectionName);
            
            // 创建索引
            _collection.EnsureIndex(x => x.Id);
            _collection.EnsureIndex(x => x.GroupDeviceId);
            _collection.EnsureIndex(x => x.Name);
        }

        /// <summary>
        /// 添加MQTT配置
        /// </summary>
        public object Insert(object param)
        {
            try
            {
                var jsonString = param.ToString()!;
                var jObject = JObject.Parse(jsonString);

                var mqttSetting = new NetworkMqttSetting();

                // 设置各个字段
                if (jObject.TryGetValue("groupDeviceId", out var groupDeviceIdToken))
                {
                    mqttSetting.GroupDeviceId = groupDeviceIdToken.Value<int>();
                }
                if (jObject.TryGetValue("name", out var nameToken))
                {
                    mqttSetting.Name = nameToken.ToString();
                }
                if (jObject.TryGetValue("config", out var configToken))
                {                   
                    mqttSetting.Config = configToken.ToString();
                }
                // 检查是否已存在同名配置（在同一设备内）
                if (!string.IsNullOrEmpty(mqttSetting.Name))
                {
                    var existingSetting = _collection.FindOne(x => x.Name == mqttSetting.Name && x.GroupDeviceId == mqttSetting.GroupDeviceId);
                    if (existingSetting != null)
                    {
                        return ApiResponse.Fail("插入失败: 该设备内已存在同名MQTT配置");
                    }
                }

                if (!string.IsNullOrEmpty(mqttSetting.Config))
                {
                    var existingSetting = _collection.FindOne(x => x.Name == mqttSetting.Name && x.GroupDeviceId == mqttSetting.GroupDeviceId);
                    if (existingSetting != null)
                    {
                        return ApiResponse.Fail("插入失败: 该设备内已存在同名MQTT配置");
                    }
                }

                var id = _collection.Insert(mqttSetting);
                // 将configToken转换为json对象,并修改id替换为id字段
                var config = JObject.Parse(mqttSetting.Config);
                config["id"] = id.AsInt32;
                mqttSetting.Config = config.ToString();
                return ApiResponse.Success(id.AsInt32, "MQTT配置创建成功");
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"创建MQTT配置失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 根据ID查找MQTT配置
        /// </summary>
        public object FindById(object param)
        {
            try
            {
                int id = Convert.ToInt32(param);
                var result = _collection.FindById(id);
                if (result == null)
                    return ApiResponse.Fail("MQTT配置不存在", null, ApiResponseCode.NotFound);
                return ApiResponse.Success(result);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"查询MQTT配置失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 查找所有MQTT配置
        /// </summary>
        public object FindAll(object? param = null)
        {
            try
            {
                List<NetworkMqttSetting> list;

                if (param != null)
                {
                    // 根据设备ID过滤配置
                    int groupDeviceId = Convert.ToInt32(param);
                    list = _collection.Find(s => s.GroupDeviceId == groupDeviceId).ToList();
                }
                else
                {
                    // 获取所有配置
                    list = _collection.FindAll().ToList();
                }

                var objectArray = list.Select(p => new
                {
                    id = p.Id,
                    name = p.Name,
                    groupDeviceId = p.GroupDeviceId,
                    config = Newtonsoft.Json.JsonConvert.DeserializeObject(p.Config),
                }).ToArray();
                // 序列化为JSON字符串然后反序列化为动态对象，确保返回纯JSON格式
                var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(objectArray);
                return ApiResponse.Success(jsonString);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"查询MQTT配置列表失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 更新MQTT配置
        /// </summary>
        public object Update(object param)
        {
            try
            {
                var jsonString = param.ToString()!;
                var jObject = JObject.Parse(jsonString);

                // 解析ID
                if (!jObject.TryGetValue("id", out var idToken))
                {
                    return ApiResponse.Fail("更新失败: 缺少ID字段");
                }

                int id = idToken.Value<int>();

                // 获取现有记录
                var existingSetting = _collection.FindById(id);
                if (existingSetting == null)
                {
                    return ApiResponse.Fail("更新失败: MQTT配置不存在");
                }

                // // 获取config对象
                // JObject? config = null;
                // if (jObject.TryGetValue("config", out var configToken))
                // {
                //     config = configToken as JObject;
                // }
                // if (config == null)
                // {
                //     return ApiResponse.Fail("更新失败: 无效的配置数据");
                // }

                // 更新字段 - 从config对象中获取属性
                if (jObject.TryGetValue("groupDeviceId", out var groupDeviceIdToken))
                {
                    existingSetting.GroupDeviceId = groupDeviceIdToken.Value<int>();
                }
                
                if (jObject.TryGetValue("name", out var nameToken))
                {
                    existingSetting.Name = nameToken.ToString();
                }

                if (jObject.TryGetValue("config", out var configToken))
                {
                    existingSetting.Config = configToken.ToString();
                }

                // 检查在同一设备内是否已存在同名配置（排除当前更新的记录）
                if (!string.IsNullOrEmpty(existingSetting.Name))
                {
                    var duplicateSetting = _collection.FindOne(x => x.Name == existingSetting.Name && x.GroupDeviceId == existingSetting.GroupDeviceId && x.Id != id);
                    if (duplicateSetting != null)
                    {
                        return ApiResponse.Fail("更新失败: 该设备内已存在同名MQTT配置");
                    }
                }

                // 执行更新
                bool ok = _collection.Update(existingSetting);
                return ok ? ApiResponse.Success(ok, "MQTT配置更新成功") : ApiResponse.Fail("MQTT配置更新失败", ok);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"更新MQTT配置异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 删除MQTT配置
        /// </summary>
        public object Delete(object param)
        {
            try
            {
                int id = Convert.ToInt32(param);
                bool ok = _collection.Delete(id);
                return ok ? ApiResponse.Success(ok, "MQTT配置删除成功") : ApiResponse.Fail("MQTT配置删除失败", ok);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"删除MQTT配置异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 根据设备ID删除所有MQTT配置
        /// </summary>
        public object DeleteByGroupDeviceId(int groupDeviceId)
        {
            try
            {
                var count = _collection.DeleteMany(s => s.GroupDeviceId == groupDeviceId);
                return ApiResponse.Success(count, $"删除了 {count} 个MQTT配置");
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"删除MQTT配置失败: {ex.Message}");
            }
        }
        /// <summary>
        /// 获取当前硬件使用资源数量
        /// </summary>
        public int GetHardwareCount()
        {
            return _collection.Count();
        }
    }

    // 保留原有的配置类作为数据传输对象 (DTO)
    #region 配置类 (DTO)
    
    /// <summary>
    /// 本地网络配置 (DTO)
    /// </summary>
    public class NetworkLocalConfig
    {
        public string Name { get; set; } = string.Empty;
        public string IpAddress { get; set; } = string.Empty;
        public int Port { get; set; }
        public bool EnableSsl { get; set; }
        public int Timeout { get; set; } = 5000;
        // 其他网络配置属性...
    }

    /// <summary>
    /// 花生壳网络配置 (DTO)
    /// </summary>
    public class NetworkOrayConfig
    {
        public string Name { get; set; } = string.Empty;
        public string Domain { get; set; } = string.Empty;
        public int Port { get; set; }
        public string Username { get; set; } = string.Empty;
        public string Password { get; set; } = string.Empty;
        // 其他花生壳配置属性...
    }

    /// <summary>
    /// HJ212网络配置 (DTO)
    /// </summary>
    public class NetworkHj212Config
    {
        public string Name { get; set; } = string.Empty;
        public string ServerUrl { get; set; } = string.Empty;
        public string MN { get; set; } = string.Empty;
        public string Password { get; set; } = string.Empty;
        public int HeartbeatInterval { get; set; } = 30;
        // 其他HJ212配置属性...
    }

    /// <summary>
    /// MQTT网络配置 (DTO) - 这个已经被NetworkMqttSetting替代，保留作为兼容性
    /// </summary>
    public class NetworkMqttConfig
    {
        public string Name { get; set; } = string.Empty;
        public string BrokerUrl { get; set; } = string.Empty;
        public int Port { get; set; } = 1883;
        public string Username { get; set; } = string.Empty;
        public string Password { get; set; } = string.Empty;
        public string ClientId { get; set; } = string.Empty;
        public int KeepAlive { get; set; } = 60;
    }

    #endregion
}